﻿using System;
using Microsoft.Xna.Framework;

namespace Serious
{
    public struct Index2
    {
        public static readonly Index2 Zero = new Index2(0, 0);
        public static readonly Index2 One = new Index2(1, 1);
        public static readonly Index2 UnitX = new Index2(1, 0);
        public static readonly Index2 UnitY = new Index2(0, 1);

        public int X;
        public int Y;

        public Index2(int x, int y)
        {
            X = x;
            Y = y;
        }

        public static Index2 CastFromVector2(Vector2 v)
        {
            return new Index2((int)v.X, (int)v.Y);
        }

        
        public static implicit operator Vector2(Index2 i)
        {
            return new Vector2((Single)i.X, (Single)i.Y);
        }

        public static implicit operator bool(Index2 i)
        {
            return i.X != 0 || i.Y != 0;
        }

        public static bool operator ==(Index2 self, Index2 other)
        {
            return self.X == other.X && self.Y == other.Y;
        }
        public static bool operator !=(Index2 self, Index2 other)
        {
            return self.X != other.X || self.Y != other.Y;
        }

        public override bool Equals(object o)
        {
            Index2? other = o as Index2?;
            if (other != null)
            {
                return this.X == other.Value.X && this.Y == other.Value.Y;
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            int result = 923;
            result = result * 397 ^ X;
            result = result * 397 ^ Y;
            return result;
        }

        public static Index2 operator +(Index2 self, Index2 other)
        {
            return new Index2(self.X + other.X, self.Y + other.Y);
        }
        public static Index2 operator -(Index2 self, Index2 other)
        {
            return new Index2(self.X - other.X, self.Y - other.Y);
        }
        public static Index2 operator *(Index2 self, Index2 other)
        {
            return new Index2(self.X * other.X, self.Y * other.Y);
        }
        public static Index2 operator *(Index2 self, int scale)
        {
            return new Index2(self.X * scale, self.Y * scale);
        }
        public static Index2 operator /(Index2 self, Index2 other)
        {
            return new Index2(self.X / other.X, self.Y / other.Y);
        }
        public static Index2 operator /(Index2 self, int scale)
        {
            return new Index2(self.X / scale, self.Y / scale);
        }

        public static Index2 operator -(Index2 self)
        {
            return new Index2(-self.X, -self.Y);
        }

        public static Index2 Min(Index2 i1, Index2 i2)
        {
            return new Index2(Math.Min(i1.X, i2.X), Math.Min(i1.Y, i2.Y));
        }
        public static Index2 Max(Index2 i1, Index2 i2)
        {
            return new Index2(Math.Max(i1.X, i2.X), Math.Max(i1.Y, i2.Y));
        }

        public static Index2 Clamp(Index2 value, Index2 min, Index2 max)
        {
            return Min(Max(min, value), max);
        }

        public override string ToString()
        {
            return string.Format("I2{{X:{0}, Y:{1}}}", this.X, this.Y);
        }
    }
}
